package com.baoming.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.baoming.dao.ICommonDao;
import com.baoming.util.GenericSuperClass;
import com.baoming.util.PageInfo;
 

public class CommonDaoImpl<T> extends HibernateDaoSupport implements
		ICommonDao<T> {
 
	private Class<?> entity = (Class<?>) GenericSuperClass
			.getClass(this.getClass());

	public void save(T t) {
		this.getHibernateTemplate().save(t);
	}

	public void update(T t) {
		this.getHibernateTemplate().update(t);
	}

	@Resource(name = "sessionFactory")
	public final void setSessionFactoryDi(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}

	@SuppressWarnings("unchecked")
	public T findObjectById(Serializable tid) {
		return (T) this.getHibernateTemplate().get(entity, tid);
	}

	public void deleteObjectById(Serializable... tid) {
		for (Serializable id : tid) {
			Object object = this.getHibernateTemplate().get(entity, id);
			if (object != null)
				this.getHibernateTemplate().delete(object);
		}
	}

	public void deleteObjectByCollection(Collection<T> entities) {
		this.getHibernateTemplate().deleteAll(entities);
	}

	protected String orderByCondition(LinkedHashMap<String, String> ordermap) {
		StringBuffer buffer = new StringBuffer("");
		if (ordermap != null) {
			buffer.append(" order by ");
			for (Map.Entry<String, String> map : ordermap.entrySet()) {
				buffer.append("  " + map.getKey() + "  " + map.getValue()
								+ ",");
			}
			buffer.deleteCharAt(buffer.length() - 1);
		}
		return buffer.toString();
	}

	private void setParams(Query query, Object[] params) {
		for (int i = 0; params != null && i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
	}

	@SuppressWarnings("unchecked")
	public List<T> findCollectionByConditionNoPage(String hqlWhere,
			final Object[] params, LinkedHashMap<String, String> orderby) {
		String hql = "FROM " + entity.getSimpleName() + " m WHERE 1 = 1 ";
		hql = hql + hqlWhere + orderByCondition(orderby);
		final String finalHql = hql;
		List<T> list = (List<T>) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(finalHql);
						setParams(query, params);
						return query.list();
					}
				});
		return list;
	}

	public void saveObjectByCollection(Collection<T> entities) {
		this.getHibernateTemplate().saveOrUpdateAll(entities);
	}

	@SuppressWarnings("unchecked")
	public List<T> findCollectionByConditionWithPage(String hqlWhere,
			final Object[] params, LinkedHashMap<String, String> orderby,
			final PageInfo pageInfo) {
		String hql = " from " + entity.getSimpleName() + "  m where 1 = 1 ";
		String hqlOrderBy = this.orderByCondition(orderby);
		hql = hql + hqlWhere + hqlOrderBy;
		final String finalHql = hql;
		List<T> list = (List<T>) this.getHibernateTemplate().execute(
				new HibernateCallback() { 
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						// TODO Auto-generated method stub
						Query query = session.createQuery(finalHql);
						setParams(query, params);
						int totalSize = query.list().size();
						pageInfo.setTotalResult(totalSize);
						query.setFirstResult(pageInfo.getCurrentPageNow());
						query.setMaxResults(pageInfo.getPageSize());
						return query.list();
					}

				});
		return list;
	}

	@SuppressWarnings("unchecked")
	public int selectMaxRow(T t) {
		String hql = "FROM " + entity.getSimpleName() + " m WHERE 1 = 1 "; 
		final String finalHql = hql;
		List<T> list = (List<T>) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(finalHql); 
						return query.list();
					}
				});
		int maxSize = list.size() ; 
		return maxSize ;
	} 
	 
}
